package com.magoldeditor.view;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelListener;
import java.util.LinkedList;

import javax.swing.JComponent;
import javax.swing.JPanel;

import com.magoldeditor.at.MaEditorXMLException;
import com.magoldeditor.controller.MaEditorMouseListener;
import com.magoldeditor.controller.MaEditorMouseMotionListener;
import com.magoldeditor.controller.MaEditorMouseWheelListener;
import com.magoldeditor.model.IPainter;

/**
 * 
 * @author Velconia
 * @version v.2.0
 * 
 */
public class MaEditorPanel extends JPanel implements ILineDrawer, IEditor {
	
	/**
	 * serial Version ID
	 */
	private static final long serialVersionUID = 4L;
	
	/**
	 * color
	 */
	private static final Color DEF_COLOR = Color.white;
	
	/**
	 * def row
	 */
	private static final int ROW_DEF = 48;
	
	/**
	 * def col
	 */
	private static final int COL_DEF = 80;
	
	/**
	 * name
	 */
	protected String name = "MaEditorPanel";
	
	/**
	 * default Bounds
	 */
	private static final int X_DEF = 0;
	private static final int Y_DEF = 0;
	private static final int WIDTH_DEF = 800;
	private static final int HEIGHT_DEF = 480;
	
	/**
	 * color
	 */
	protected Color color = DEF_COLOR;
	
	/**
	 * mouse motion listener
	 */
	protected MaEditorMouseMotionListener mouseMotionListener = null;
	
	/**
	 * mouse listener
	 */
	protected MaEditorMouseListener mouseListener = null;
	
	/**
	 * mouse wheel listener
	 */
	protected MaEditorMouseWheelListener mouseWheelListener = null;
	
	/**
	 * key listener
	 */
	protected KeyListener keyListener = null;
	
	/**
	 * painter list
	 */
	protected LinkedList<IPainter> painterList = new LinkedList<IPainter>();
	
	/**
	 * 
	 */
	public MaEditorPanel() {
		this(null, null, null, null);
	}
	
	/**
	 * 
	 * @param name
	 */
	public MaEditorPanel(String name) {
		this(null, null, null, name);
	}
	
	/**
	 * 
	 * @param color
	 * @param name
	 */
	public MaEditorPanel(Color color, String name) {
		this(color, null, null, name);
	}
	
	/**
	 * 
	 * @param color
	 * @param mouseMotionListener
	 * @param mouseListener
	 * @param name
	 */
	public MaEditorPanel(Color color, MaEditorMouseMotionListener mouseMotionListener, MaEditorMouseListener mouseListener, String name) {
		init(color, mouseMotionListener, mouseListener, name);
		repaint();
	}
	
	@Override
	public void paintLine(Graphics g, int width, int height) {
		this.paintLine(g, width, height, ROW_DEF, COL_DEF);
	}

	@Override
	public void paintLine(Graphics g, int width, int height, int row, int col) {
		g.setColor(Color.gray);
		
		for (int i = 0; i <= row + 1; i++) {
			int tempY = i * height / row;
			g.drawRect(0, tempY, width, tempY);
		}
		
		for (int i = 0; i <= col + 1; i++) {
			int tempX = i * width / col;
			g.drawRect(tempX, 0, tempX, height);
		}
	}

	@Override
	public void paintLine(Graphics g, JComponent component) {
		this.paintLine(g, component.getWidth(), component.getHeight());
	}
	
	/**
	 * init from xml file by self
	 * @param c
	 * @param mouseMotionListener
	 * @param mouseListener
	 * @param name
	 */
	private void init(Color c, MaEditorMouseMotionListener mouseMotionListener, MaEditorMouseListener mouseListener, String name) {
		/*
		 * layout
		 */
		this.setLayout(null);
		
		/*
		 * name
		 */
		if (name != null) this.name = name;
		
		/*
		 * config
		 */
		try {
			ViewContants.initConfig(this, this.name);
		} catch (MaEditorXMLException e) {
			e.printStackTrace();
			this.setBounds(X_DEF, Y_DEF, WIDTH_DEF, HEIGHT_DEF);
		}
		
		/*
		 * color
		 */
		if (c != null) this.color = c;
		setBackground(color);
		setForeground(color);
		
		/*
		 * mouse motion listener
		 */
		if (mouseMotionListener != null) this.mouseMotionListener = mouseMotionListener;
		else this.mouseMotionListener = new MaEditorPanel.MouseMotionHandlerDef();
		this.addMouseMotionListener(this.mouseMotionListener);
		
		/*
		 * mouse listener
		 */
		if (mouseListener != null) this.mouseListener = mouseListener;
		else  this.mouseListener = new MaEditorPanel.MouseHandlerDef();
		this.addMouseListener(this.mouseListener);
	
		/*
		 * refresh the ui
		 */
		this.repaint();
	}

	public void setMouseMotionListener(MaEditorMouseMotionListener mouseMotionListener) {
		this.mouseMotionListener = mouseMotionListener;
		this.addMouseMotionListener(mouseMotionListener);
	}
	
	public MaEditorMouseMotionListener getMouseMotionListener() {
		return this.mouseMotionListener;
	}
	
	public void setMouseListener(MaEditorMouseListener mouseListener) {
		this.mouseListener = mouseListener;
		this.addMouseListener(mouseListener);
	}
	
	public MaEditorMouseListener getMouseListener() {
		return this.mouseListener;
	}

	public void setMouseMotionWheelListener(MaEditorMouseWheelListener listener) {
		if (listener != null) {
			this.mouseWheelListener = listener;
			this.addMouseWheelListener(listener);
		}
	}
	
	public MouseWheelListener getMouseMotionWheelListener() {
		return this.mouseWheelListener;
	}
	
	public void setKeyListener(KeyListener keyListener) {
		if (keyListener != null) {
			this.keyListener = keyListener;
			this.addKeyListener(keyListener);
		}
		
		System.out.println("add key listener");
 	}
	
	public KeyListener getKeyListener() {
		return this.keyListener;
	}

	@Override
	public void edit(IPainter[] painterList) {
		if (painterList != null) 
			for (int i = 0; i < painterList.length; i++) 
				this.painterList.add(painterList[i]);
		
		repaint();
	}

	@Override
	public void addPainter(IPainter painter) {
		if (painter != null) this.painterList.add(painter);
	}

	@Override
	public void deletePainter(IPainter painter) {
		if (painter != null) this.painterList.remove(painter);
	}

	public void setPainter(IPainter painter, int index) {
		if (painter != null) this.painterList.add(index, painter);
	}

	@Override
	public void setPainterList(IPainter[] painterList) {
		for (int i = 0; i < painterList.length; i++) {
			this.painterList.add(i, painterList[i]);
		}
	}

	@Override
	public IPainter getPainter(int index) {
		return this.painterList.get(index);
	}

	@Override
	public IPainter[] getPainterList(IPainter[] p) {
		if (p.length < this.painterList.size()) p = new IPainter[this.painterList.size()];
		return this.painterList.toArray(p);
	}
	
	/**
	 * 
	 * @author Velconia
	 * 
	 */
	class MouseMotionHandlerDef implements MaEditorMouseMotionListener {

		@Override
		public void mouseDragged(MouseEvent e) {
			System.out.println(name + " mouse dragged at (" + e.getX() + "," + e.getY() + ")");
		}

		@Override
		public void mouseMoved(MouseEvent e) {
			System.out.println(name + " mouse moved at (" + e.getX() + "," + e.getY() + ")");
		}

		@Override
		public void refresh() {
			
		}
	}
	
	/**
	 * 
	 * @author Velconia
	 *
	 */
	class MouseHandlerDef implements MaEditorMouseListener {

		@Override
		public void mouseClicked(MouseEvent e) {
			System.out.println(name + " mouse clicked at (" + e.getX() + "," + e.getY() + ")");
		}

		@Override
		public void mouseEntered(MouseEvent e) {
			System.out.println(name + " mouse entered at (" + e.getX() + "," + e.getY() + ")");
		}

		@Override
		public void mouseExited(MouseEvent e) {
			System.out.println(name + " mouse exited at (" + e.getX() + "," + e.getY() + ")");
		}

		@Override
		public void mousePressed(MouseEvent e) {
			System.out.println(name + " mouse pressed at (" + e.getX() + "," + e.getY() + ")");
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			System.out.println(name + " mouse released at (" + e.getX() + "," + e.getY() + ")");
		}

		@Override
		public void refresh() {
			
		}
	}

	@Override
	public void focusOn() {
		this.requestFocus();
	}
}
